﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using Antlr;
using Antlr.Runtime;
using Antlr.Runtime.Tree;
using MathNet.Numerics.LinearAlgebra.Double;
using CudaTranslator;
using cudaMatrix;
using cudaTranslator;
using System.Diagnostics;
using Microsoft.Win32;

namespace cudaTranslatorGUI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Compute()
        {
            try
            {
                Stopwatch sw = new Stopwatch();
                //przygotowanie do parsowania
                ANTLRStringStream sStream = new ANTLRStringStream(input.Text);
                CudaTranslatorLexer lexer = new CudaTranslatorLexer(sStream);
                CommonTokenStream tStream = new CommonTokenStream(lexer);
                CudaTranslatorParser parser = new CudaTranslatorParser(tStream);

                //parsowanie
                CudaTranslatorParser.prog_return parseReturn = parser.prog();

                // tworzy drzewo
                CommonTree Tree = (CommonTree)parseReturn.Tree;

                //stream do czytania wyjscia treewalkera
                StringWriter stream = new StringWriter();

                //tworzy klasę analizującą i zaczyna pracować
                TreeWalker walker = new TreeWalker(parser, stream);
                sw.Start();
                walker.WalkAndAnalyse(Tree);
                sw.Stop();

                stream.WriteLine();
                stream.WriteLine("Time Elapsed: " + sw.Elapsed);
                stream.Flush();
                output.Text = stream.ToString();
            }
            catch (Exception e)
            {
                output.Text = e.Message;
            }
        }

        private void OnKeyDownHandler(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.F5)
            {
                Compute();
            }
        }

        public void UseCpu(object sender, EventArgs e)
        {
            MatrixFactory.COMPUTER = ComputationHost.CPU;
        }

        public void UseCuda(object sender, EventArgs e)
        {
            MatrixFactory.COMPUTER = ComputationHost.CUDA;
        }

        public void LoadFile(object sender, EventArgs e)
        {
            Stream myStream = null;
            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            openFileDialog1.Filter = "CudaTranslatorCode (*.ctc)|*.ctc|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 1;
            openFileDialog1.RestoreDirectory = true;

            if (openFileDialog1.ShowDialog() != null)
            {
                try
                {
                    if ((myStream = openFileDialog1.OpenFile()) != null)
                    {
                        using (myStream)
                        {
                            input.Text = new StreamReader(myStream).ReadToEnd();
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
                }
            }
        }

        public void SaveFile(object sender, EventArgs e)
        {
            FileStream myStream = null;
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Filter = "CudaTranslatorCode (*.ctc)|*.ctc|All files (*.*)|*.*";
            saveFileDialog1.FilterIndex = 1;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() != null)
            {
                try
                {
                    if ((myStream = (FileStream)saveFileDialog1.OpenFile()) != null)
                    {
                        using (myStream)
                        {
                            myStream.Write(Encoding.ASCII.GetBytes(input.Text), 0, Encoding.ASCII.GetBytes(input.Text).Length);
                        }
                    }
                }
                catch (Exception ex)
                {
                    
                }
            }
        }

        public void GoGOPowerRangers(object sender, EventArgs e)
        {
            Compute();
        }
    }
}
